package org.fast.develop.logicflow.runtime.expression;

/**
 * 项 目 名：gs-tto-data-mapping
 * 源文件名：com.geekstorm.tto.datamapping.core.expression.JuelExpression
 * 文件版本：1.0.0
 * 创建人： 莫寅
 * 创建日期：2020-07-23 11:30
 * 修改作者：莫寅
 * 修改日期：2020-07-23 11:30
 * 文件描述：
 * By：2020 © CompanyName  , Inc. All Rights Reserved.
 */


import javax.el.*;

/**
 * Expression implementation backed by a JUEL {@link ValueExpression}.
 *
 * @author Frederik Heremans
 * @author Joram Barrez
 */
public class JuelExpression implements Expression {

	protected String expressionText;

	protected ValueExpression valueExpression;

	private ExpressionManager expressionManager;

	public JuelExpression(ValueExpression valueExpression, String expressionText, ExpressionManager expressionManager) {
		this.valueExpression = valueExpression;
		this.expressionText = expressionText;
		this.expressionManager = expressionManager;
	}

	@Override
	public Object getValue(VariableScope variableScope) {
		ELContext elContext = expressionManager.getElContext(variableScope);
		try {
			ExpressionGetInvocation invocation = new ExpressionGetInvocation(valueExpression, elContext);

			invocation.proceed();
			return invocation.getInvocationResult();
		}
		catch (PropertyNotFoundException pnfe) {
			throw new IllegalArgumentException("Unknown property used in expression: " + expressionText, pnfe);
		}
		catch (MethodNotFoundException mnfe) {
			throw new IllegalArgumentException("Unknown method used in expression: " + expressionText, mnfe);
		}
		catch (ELException ele) {
			throw new IllegalArgumentException("Error while evaluating expression: " + expressionText, ele);
		}
		catch (Exception e) {
			throw new IllegalArgumentException("Error while evaluating expression: " + expressionText, e);
		}
	}

	@Override
	public void setValue(Object value, VariableScope variableScope) {
		ELContext elContext = expressionManager.getElContext(variableScope);
		try {
			ExpressionSetInvocation invocation = new ExpressionSetInvocation(valueExpression, elContext, value);
			invocation.proceed();
		}
		catch (Exception e) {
			throw new IllegalArgumentException("Error while evaluating expression: " + expressionText, e);
		}
	}

	@Override
	public String toString() {
		if (valueExpression != null) {
			return valueExpression.getExpressionString();
		}
		return super.toString();
	}

	@Override
	public String getExpressionText() {
		return expressionText;
	}

}
